package com.wyzz.hr.bo.impl;

import com.wyzz.hr.base.BaseAction;
import com.wyzz.hr.base.Constants;
import com.wyzz.hr.base.Status;
import com.wyzz.hr.bo.ICompaplanBo;
import com.wyzz.hr.bo.IEmpSalaryAcctitemsBo;
import com.wyzz.hr.bo.ISalaryconfBo;
import com.wyzz.hr.dao.ICompaplanDAO;
import com.wyzz.hr.dao.IStatusDAO;
import com.wyzz.hr.pojo.Employee;
import com.wyzz.hr.pojo.Empsalaryacctitems;
import com.wyzz.hr.pojo.Empsalaryadj;
import com.wyzz.hr.pojo.Empsalaryconfig;
import com.wyzz.hr.spring.SpringBeanFactory;
import com.wyzz.hr.util.Pager;

import java.io.PrintStream;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import org.hibernate.FetchMode;
import org.hibernate.criterion.*;

public class CompaplanBoImpl implements ICompaplanBo, Status, Constants {

	public CompaplanBoImpl() {
	}

	public boolean deleteCompaplan(Empsalaryadj empcompaplan) {
		if (empcompaplan == null)
			return false;
		try {
			compaplanDAO.deleteObject(empcompaplan);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	public List getObjects(Class clas, String fetch[]) {
		return compaplanDAO.getObjects(clas, fetch);
	}

	public Empsalaryadj loadCompaplan(Object id, String fetch[]) {
		return (Empsalaryadj) compaplanDAO.loadObject(Empsalaryadj.class, id,
				fetch, new boolean[0]);
	}

	public boolean insertCompaplan(Empsalaryadj compaplan, String currentuserNo) {
		try {
			Date today = new Date();
			compaplan.setEsaCreateTime(today);
			compaplan.setEsaLastChangeTime(today);
			Employee employee = new Employee(currentuserNo);
			compaplan.setEsaCreateBy(employee);
			compaplan.setEsaLastChangeBy(employee);
			compaplan.setEsaChanged(Integer.valueOf(0));
			compaplan.encryEmpSalaryAdj(compaplan);
			compaplanDAO.saveObject(compaplan);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	public Integer searchCompaplanSubmitStatus(String yearmonth) {
		int year = Integer.parseInt(yearmonth.substring(0, 4));
		int month = Integer.parseInt(yearmonth.substring(4));
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(Empsalaryadj.class);
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		try {
			Date date = dateFormat
					.parse((new StringBuilder()).append(year).append("-")
							.append(month).append("-").append(1).toString());
			detachedCriteria.add(Restrictions.eq(
					Empsalaryadj.PROP_ESA_EFFDATE_PRO, date));
			detachedCriteria.add(Restrictions.eq(Empsalaryadj.PROP_ESA_STATUS,
					Integer.valueOf(11)));
			Integer counts = Integer.valueOf(compaplanDAO
					.findRowCountByCriteria(detachedCriteria));
			return counts;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return Integer.valueOf(0);
	}

	public List mysearchCompaplan(DetachedCriteria dc, Pager page) {
		if (page == null) {
			BaseAction.addOrders(dc, page, new String[] { (new StringBuilder())
					.append(Empsalaryadj.PROP_ESA_EMPNO).append("-up")
					.toString() });
			return compaplanDAO.findByCriteria(dc);
		} else {
			BaseAction.addOrders(dc, page, new String[] {
					(new StringBuilder()).append(
							Empsalaryadj.PROP_ESA_EFFDATE_PRO).append("-down")
							.toString(),
					(new StringBuilder()).append("emp.").append(
							Employee.PROP_EMP_NAME).append("-up").toString() });
			page.splitPage(dc);
			return compaplanDAO.findByCriteria(dc, page.getPageSize(), page
					.getCurrentPage());
		}
	}

	private Empsalaryadj calEsaByItems(Empsalaryadj esa, Map itemCache)
			throws Exception {
		Class ownerClass = esa.getClass();
		String cur = esa.getEsaEsavIdCur().getId();
		String pro = esa.getEsaEsavIdPro().getId();
		List<Empsalaryacctitems> curItems = (List) itemCache.get(cur);
		for (Empsalaryacctitems item : curItems) {
			if (item.getEsaiEsdd().getEsddDataType().intValue() == 1) {
				Method esaMethod = ownerClass.getMethod("getEsaColumn"
						+ item.getEsaiDataSeq() + "Cur", new Class[0]);
				esa.setBasicSalary((BigDecimal) esaMethod.invoke(esa,
						new Object[0]));
			}
			if (item.getEsaiEsdd().getEsddDataType().intValue() == 8) {
				Method esaMethod = ownerClass.getMethod("getEsaColumn"
						+ item.getEsaiDataSeq() + "Cur", new Class[0]);
				esa.setMoneybeforetax((BigDecimal) esaMethod.invoke(esa,
						new Object[0]));
			}
		}
		List<Empsalaryacctitems> proItems = (List) itemCache.get(pro);
		for (Empsalaryacctitems item : proItems) {
			if (item.getEsaiEsdd().getEsddDataType().intValue() == 1) {
				Method esaMethod = ownerClass.getMethod("getEsaColumn"
						+ item.getEsaiDataSeq() + "Pro", new Class[0]);
				esa.setNewBasicSalary((BigDecimal) esaMethod.invoke(esa,
						new Object[0]));
			}
			if (item.getEsaiEsdd().getEsddDataType().intValue() == 8) {
				Method esaMethod = ownerClass.getMethod("getEsaColumn"
						+ item.getEsaiDataSeq() + "Pro", new Class[0]);
				esa.setNewmoneybeforetax((BigDecimal) esaMethod.invoke(esa,
						new Object[0]));
			}
		}
		return esa;
	}

	private Empsalaryadj calEmpsalaryadj(Empsalaryadj empsalaryadj,
			List relatedesaiList) {
		Class ownerClass = empsalaryadj.getClass();
		try {
			Iterator i$ = relatedesaiList.iterator();
			do {
				if (!i$.hasNext())
					break;
				Empsalaryacctitems esai = (Empsalaryacctitems) i$.next();
				if (esai.getEsaiEsdd().getEsddDataType().intValue() == 1) {
					Method esaMethod = ownerClass.getMethod(
							(new StringBuilder()).append("getEsaColumn")
									.append(esai.getEsaiDataSeq())
									.append("Pro").toString(), new Class[0]);
					empsalaryadj.setNewBasicSalary((BigDecimal) esaMethod
							.invoke(empsalaryadj, new Object[0]));
				}
				if (esai.getEsaiEsdd().getEsddDataType().intValue() == 8) {
					Method esaMethod = ownerClass.getMethod(
							(new StringBuilder()).append("getEsaColumn")
									.append(esai.getEsaiDataSeq())
									.append("Pro").toString(), new Class[0]);
					empsalaryadj.setNewmoneybeforetax((BigDecimal) esaMethod
							.invoke(empsalaryadj, new Object[0]));
				}
			} while (true);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return empsalaryadj;
	}

	public int hasSalaryAdjByAcctVersion(String acctversionId) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(Empsalaryadj.class);
		detachedCriteria.add(Restrictions.or(Restrictions.eq("esaEsavIdCur.id",
				acctversionId), Restrictions.eq("esaEsavIdPro.id",
				acctversionId)));
		detachedCriteria.setProjection(Projections.rowCount());
		List list = compaplanDAO.findByCriteria(detachedCriteria);
		return ((Integer) list.get(0)).intValue();
	}

	public List mysearchBatchCompaplan(DetachedCriteria dc, Pager page) {
		BaseAction.addOrders(dc, page, new String[] { (new StringBuilder())
				.append("emp.").append(Employee.PROP_EMP_NAME).append("-up")
				.toString() });
		page.splitPage(dc);
		return compaplanDAO.findByCriteria(dc, page.getPageSize(), page
				.getCurrentPage());
	}

	public boolean calcSalaryConfWithComp(List configList) {
		if (configList.isEmpty())
			return false;
		IEmpSalaryAcctitemsBo empSalaryAcctitemsBo = (IEmpSalaryAcctitemsBo) SpringBeanFactory
				.getBean("empsalaryacctitemsBo");
		Map itemsMap = empSalaryAcctitemsBo.getItemsBySalaryConf(configList);
		Map compaplansMap = getEmpsalaryadjMap();
		Empsalaryconfig salaryconf;
		ISalaryconfBo salaryconfBo;
		for (Iterator i$ = configList.iterator(); i$.hasNext(); salaryconfBo
				.calcSalaryConfByType((List) itemsMap.get(salaryconf
						.getEscEsavId().getId()), salaryconf)) {
			salaryconf = (Empsalaryconfig) i$.next();
			salaryconf.decryEmpSalaryConf(salaryconf);
			Empsalaryadj compaplanFromDB = (Empsalaryadj) compaplansMap
					.get(salaryconf.getEmployee().getId());
			if (compaplanFromDB != null) {
				compaplanFromDB.decryEmpSalaryAdj(compaplanFromDB);
				calEmpsalaryadj(compaplanFromDB, (List) itemsMap
						.get(compaplanFromDB.getEsaEsavIdPro().getId()));
				salaryconf.setComp(compaplanFromDB);
				salaryconf.setNewBasicSalary(compaplanFromDB
						.getNewBasicSalary());
				salaryconf.setNewmoneybeforetax(compaplanFromDB
						.getNewmoneybeforetax());
			}
			salaryconfBo = (ISalaryconfBo) SpringBeanFactory
					.getBean("salaryconfBo");
		}

		return true;
	}

	public boolean calcSalaryAdj(List result) {
		IEmpSalaryAcctitemsBo empSalaryAcctitemsBo = (IEmpSalaryAcctitemsBo) SpringBeanFactory
				.getBean("empsalaryacctitemsBo");
		Map itemsMap = empSalaryAcctitemsBo.getItemsBySalaryAdj(result);
		try {
			for (Iterator i$ = result.iterator(); i$.hasNext();) {
				Empsalaryadj esa = (Empsalaryadj) i$.next();
				esa.decryEmpSalaryAdj(esa);
				esa = calEsaByItems(esa, itemsMap);
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return true;
	}

	/**
	 * @deprecated Method createAcctItemsMap is deprecated
	 */

	private Map createAcctItemsMap() {
		DetachedCriteria dcforEsa = DetachedCriteria
				.forClass(Empsalaryacctitems.class);
		dcforEsa.setFetchMode("esaiEsav", FetchMode.JOIN);
		dcforEsa.addOrder(Order.asc("esaiDataSeq"));
		List esaiList = compaplanDAO.findByCriteria(dcforEsa);
		Map itemsMap = new HashMap();
		Empsalaryacctitems item;
		List items;
		for (Iterator i$ = esaiList.iterator(); i$.hasNext(); itemsMap.put(item
				.getEsaiEsav().getId(), items)) {
			item = (Empsalaryacctitems) i$.next();
			items = (List) itemsMap.get(item.getEsaiEsav().getId());
			if (items == null)
				items = new ArrayList();
			items.add(item);
		}

		return itemsMap;
	}

	private Empsalaryconfig calSalaryConfig(Empsalaryconfig salaryConfig,
			List esaiList) {
		Class ownerClass = Empsalaryconfig.class;
		try {
			Iterator i$ = esaiList.iterator();
			do {
				if (!i$.hasNext())
					break;
				Empsalaryacctitems esai = (Empsalaryacctitems) i$.next();
				if (esai.getEsaiEsdd().getEsddDataType().intValue() == 1) {
					Method escMethod = ownerClass.getMethod(
							(new StringBuilder()).append("getEscColumn")
									.append(esai.getEsaiDataSeq()).toString(),
							new Class[0]);
					salaryConfig.setBasicSalary((BigDecimal) escMethod.invoke(
							salaryConfig, new Object[0]));
				}
				if (esai.getEsaiEsdd().getEsddDataType().intValue() == 8) {
					Method escMethod = ownerClass.getMethod(
							(new StringBuilder()).append("getEscColumn")
									.append(esai.getEsaiDataSeq()).toString(),
							new Class[0]);
					salaryConfig.setMoneybeforetax((BigDecimal) escMethod
							.invoke(salaryConfig, new Object[0]));
				}
			} while (true);
			return salaryConfig;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public boolean updateSalaryConf(Empsalaryadj compaplan, String currentUserId) {
		try {
			Empsalaryconfig salaryconfigFromDB = (Empsalaryconfig) compaplanDAO
					.loadObject(Empsalaryconfig.class, compaplan.getEsaEmpno()
							.getId(), null, new boolean[0]);
			salaryconfigFromDB.setEscLastChangeBy(currentUserId);
			salaryconfigFromDB.setEscLastChangeTime(new Date());
			salaryconfigFromDB.setEscLastEffDate(compaplan.getEsaCurEffDate());
			salaryconfigFromDB
					.setEscLastIncrRate(compaplan.getEsaCurIncrRate());
			Class escClass = salaryconfigFromDB.getClass();
			Class esaClass = compaplan.getClass();
			for (int i = 1; i <= 48; i++) {
				Method esaMethod = esaClass.getMethod((new StringBuilder())
						.append("getEsaColumn").append(i).append("Pro")
						.toString(), new Class[0]);
				Method escMethod = escClass.getMethod((new StringBuilder())
						.append("setEscColumn").append(i).toString(),
						new Class[] { BigDecimal.class });
				escMethod.invoke(salaryconfigFromDB,
						new Object[] { (BigDecimal) esaMethod.invoke(compaplan,
								new Object[0]) });
			}

			salaryconfigFromDB.setEscEsavId(compaplan.getEsaEsavIdPro());
			if (compaplan.getEsaJobgradePro() != null)
				salaryconfigFromDB
						.setEscJobgrade(compaplan.getEsaJobgradePro());
			compaplanDAO.updateObject(salaryconfigFromDB);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	public Empsalaryadj loadCompaplanInfoByEmpNo(String empNo) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(Empsalaryadj.class);
		detachedCriteria.add(Restrictions.eq("esaEmpno.id", empNo));
		detachedCriteria.add(Restrictions.eq("esaStatus", Integer.valueOf(11)));
		List result = compaplanDAO.findByCriteria(detachedCriteria);
		if (result.size() > 0)
			return (Empsalaryadj) result.get(0);
		else
			return null;
	}

	public Empsalaryadj loadCompaplanInfoByEmpNo(String empNo, Date date) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(Empsalaryadj.class);
		detachedCriteria.add(Restrictions.eq("esaEmpno.id", empNo));
		detachedCriteria.add(Restrictions.eq("esaStatus", Integer.valueOf(41)));
		detachedCriteria.add(Restrictions.ge("esaCurEffDate", date));
		detachedCriteria.addOrder(Order.asc("esaCurEffDate"));
		List result = compaplanDAO.findByCriteria(detachedCriteria);
		if (result.size() > 0)
			return (Empsalaryadj) result.get(0);
		else
			return null;
	}

	private Map getEmpsalaryadjMap() {
		Map empsalaryadjs = new HashMap();
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(Empsalaryadj.class);
		detachedCriteria.setFetchMode("esaEcptypeId", FetchMode.JOIN);
		detachedCriteria.setFetchMode("esaJobgradePro", FetchMode.JOIN);
		detachedCriteria.add(Restrictions.eq("esaStatus", Integer.valueOf(11)));
		List result = compaplanDAO.findByCriteria(detachedCriteria);
		Empsalaryadj adj;
		for (Iterator i$ = result.iterator(); i$.hasNext(); empsalaryadjs.put(
				adj.getEsaEmpno().getId(), adj))
			adj = (Empsalaryadj) i$.next();

		return empsalaryadjs;
	}

	public void updateCompaplan(Empsalaryadj compaplan,
			Empsalaryadj compaplanFromDB, String currentuserNo) {
		compaplanFromDB.setEsaComments(compaplan.getEsaComments());
		compaplanFromDB.setEsaCurIncrRate(compaplan.getEsaCurIncrRate());
		compaplanFromDB.setEsaCurIncrRate1(compaplan.getEsaCurIncrRate1());
		compaplanFromDB.setEsaJobgradePro(compaplan.getEsaJobgradePro());
		compaplanFromDB.setEsaEsavIdPro(compaplan.getEsaEsavIdPro());
		compaplanFromDB.setEsaEcptypeId(compaplan.getEsaEcptypeId());
		compaplanFromDB.setEsaCurEffDate(compaplan.getEsaCurEffDate());
		compaplanFromDB.setEsaLastChangeTime(new Date());
		compaplanFromDB.setEsaLastChangeBy(new Employee(currentuserNo));
		compaplanFromDB.setEsaChanged(Integer.valueOf(0));
		try {
			Class oldClass = compaplanFromDB.getClass();
			Class compaClass = compaplan.getClass();
			for (int i = 1; i <= 48; i++) {
				Method compaMethod = compaClass.getMethod((new StringBuilder())
						.append("getEsaColumn").append(i).append("Cur")
						.toString(), new Class[0]);
				Method oldMethod = oldClass.getMethod((new StringBuilder())
						.append("setEsaColumn").append(i).append("Cur")
						.toString(), new Class[] { BigDecimal.class });
				oldMethod.invoke(compaplanFromDB,
						new Object[] { (BigDecimal) compaMethod.invoke(
								compaplan, new Object[0]) });
				compaMethod = compaClass.getMethod((new StringBuilder())
						.append("getEsaColumn").append(i).append("Pro")
						.toString(), new Class[0]);
				oldMethod = oldClass.getMethod((new StringBuilder()).append(
						"setEsaColumn").append(i).append("Pro").toString(),
						new Class[] { BigDecimal.class });
				oldMethod.invoke(compaplanFromDB,
						new Object[] { (BigDecimal) compaMethod.invoke(
								compaplan, new Object[0]) });
			}

			compaplanFromDB.encryEmpSalaryAdj(compaplanFromDB);
			compaplanDAO.updateObject(compaplanFromDB);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public boolean updateCompaplanForSlary(String yearmonth, String currentEmpNo) {
		int year = Integer.parseInt(yearmonth.substring(0, 4));
		int month = Integer.parseInt(yearmonth.substring(4));
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(Empsalaryadj.class);
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		try {
			Date date = dateFormat
					.parse((new StringBuilder()).append(year).append("-")
							.append(month).append("-").append(1).toString());
			detachedCriteria.add(Restrictions.eq(
					Empsalaryadj.PROP_ESA_EFFDATE_PRO, date));
			detachedCriteria.add(Restrictions.eq(Empsalaryadj.PROP_ESA_STATUS,
					Integer.valueOf(11)));
			List result = compaplanDAO.findByCriteria(detachedCriteria);
			Empsalaryadj empcompaplan;
			for (Iterator i$ = result.iterator(); i$.hasNext(); compaplanDAO
					.updateObject(empcompaplan)) {
				empcompaplan = (Empsalaryadj) i$.next();
				updateSalaryConf(empcompaplan, currentEmpNo);
				empcompaplan.setEsaStatus(Integer.valueOf(41));
			}

			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	public List getCompStatus() {
		return statusDAO.getStatusByTable("empsalaryadj");
	}

	public int updateBackupSalaryConfig(String empId) {
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(Empsalaryadj.class);
		detachedCriteria.add(Restrictions.eq("esaEmpno.id", empId));
		detachedCriteria.addOrder(Order.desc("esaCurEffDate"));
		List list = compaplanDAO.findByCriteria(detachedCriteria);
		DetachedCriteria detachedC = DetachedCriteria
				.forClass(Empsalaryconfig.class);
		detachedC.add(Restrictions.eq("employee.id", empId));
		List configList = compaplanDAO.findByCriteria(detachedC);
		Empsalaryconfig config = (Empsalaryconfig) configList.get(0);
		if (list.size() == 0)
			return 0;
		Empsalaryadj salaryadj = (Empsalaryadj) list.get(0);
		int status = salaryadj.getEsaStatus().intValue();
		if (status == 11)
			return 2;
		try {
			Class ownerClass = config.getClass();
			Class adjClass = salaryadj.getClass();
			for (int i = 1; i <= 48; i++) {
				Method adjMethod = adjClass.getMethod((new StringBuilder())
						.append("getEsaColumn").append(i).append("Cur")
						.toString(), new Class[0]);
				Object object = adjMethod.invoke(salaryadj, new Object[0]);
				if (object != null) {
					BigDecimal value = (BigDecimal) object;
					Method escMethod = ownerClass.getMethod(
							(new StringBuilder()).append("setEscColumn")
									.append(i).toString(),
							new Class[] { BigDecimal.class });
					escMethod.invoke(config, new Object[] { value });
				}
			}

			compaplanDAO.deleteObject(salaryadj);
			if (status == 41)
				compaplanDAO.updateObject(config);
			else
				compaplanDAO.deleteObject(config);
			return 1;
		} catch (Exception e) {
			System.out.println(e);
		}
		return 0;
	}

	public List getCompaItemsById(String id, String curOrpro) {
		Empsalaryadj compa = loadCompaplan(id, null);
		if (compa == null)
			return null;
		compa.decryEmpSalaryAdj(compa);
		IEmpSalaryAcctitemsBo empSalaryAcctitemsBo = (IEmpSalaryAcctitemsBo) SpringBeanFactory
				.getBean("empsalaryacctitemsBo");
		Empsalaryacctitems item = new Empsalaryacctitems();
		List esacItems;
		Class ownerClass;
		if (curOrpro.equalsIgnoreCase("cur")) {
			esacItems = empSalaryAcctitemsBo.getItemsByAcctversion(compa
					.getEsaEsavIdCur().getId());
			ownerClass = compa.getClass();
			try {
				for (int i = 0; i < esacItems.size(); i++) {
					item = (Empsalaryacctitems) esacItems.get(i);
					Method escMethod = ownerClass.getMethod(
							(new StringBuilder()).append("getEsaColumn")
									.append(item.getEsaiDataSeq())
									.append("Cur").toString(), new Class[0]);
					item.setItemConfigValue((BigDecimal) escMethod.invoke(
							compa, new Object[0]));
				}

			} catch (Exception e) {
				e.printStackTrace();
				return null;
			}
			return esacItems;
		}
		esacItems = empSalaryAcctitemsBo.getItemsByAcctversion(compa
				.getEsaEsavIdPro().getId());
		ownerClass = compa.getClass();
		try {
			for (int i = 0; i < esacItems.size(); i++) {
				item = (Empsalaryacctitems) esacItems.get(i);
				Method escMethod = ownerClass.getMethod((new StringBuilder())
						.append("getEsaColumn").append(item.getEsaiDataSeq())
						.append("Pro").toString(), new Class[0]);
				item.setItemConfigValue((BigDecimal) escMethod.invoke(compa,
						new Object[0]));
			}

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return esacItems;
	}

	public IStatusDAO getStatusDAO() {
		return statusDAO;
	}

	public void setStatusDAO(IStatusDAO statusDAO) {
		this.statusDAO = statusDAO;
	}

	public ICompaplanDAO getCompaplanDAO() {
		return compaplanDAO;
	}

	public void setCompaplanDAO(ICompaplanDAO compaplanDAO) {
		this.compaplanDAO = compaplanDAO;
	}

	private ICompaplanDAO compaplanDAO;
	private IStatusDAO statusDAO;
}
